package com.idroc.coelacanth.core.message;
 
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 消息类型
 * @author 赤脚詹(yuyoo4j@163.com)
 * @date Aug 17, 2009 4:13:15 PM 
 * @memo:
 */
public class MessageType {
	
	/**
	 * 无效消息类型, 值: -1;
	 */
	public static int INVALID_MESSAGE_TYPE = -1;	
	/**
	 * 已注册消息类型库
	 */
	private static Map<Integer, MessageType> repository = new ConcurrentHashMap<Integer, MessageType>();
	/**
	 * 消息Id
	 */
	private int msgId = -1;
	/**
	 * 消息名字
	 */
	private String msgName = null;
	/**
	 * 实体消息的Class
	 */
	private Class<? extends Message> msgMeta = null; 
		
	/**
	 * 创建消息类型
	 * @param id -- 消息ID
	 * @param name -- 消息名字
	 * @param meta -- 实体消息的Class
	 * @return -- 是否注册成功
	 */
	private static MessageType newInstance(Class<? extends Message> meta) {
		 
		MessageType type = new MessageType(meta);
		return type;
	} 
	
	/**
	 * 注册消息
	 * @param type -- 消息类型
	 */
	public static MessageType registry(Class<? extends Message> meta) {
		
		MessageType type = get(meta);
		if (null == type) {
			type = newInstance(meta);
			Integer key = Integer.valueOf(type.msgId);
			repository.put(key, type);
		}
		return type;
	}
	
	/**
	 * 根据消息ID查找某个消息类型
	 * @param id -- 消息ID
	 * @return -- 消息类型
	 */
	public static MessageType get(int id) {
		
		Integer key = Integer.valueOf(id);
		return repository.get(key);
	} 
	
	/**
	 * 根据消息Class查找某个消息类型
	 * @param msgClazz -- 消息Class
	 * @return -- 消息类型
	 */
	public static MessageType get(Class<? extends Message> msgClazz) {
	
		int msgId = msgClazz.getName().hashCode();
		return get(msgId);
	}
	
	@Override
	public boolean equals(Object obj) { 
		
		if (null != obj && obj instanceof MessageType) {			
			MessageType o = (MessageType) obj;
			if (this.msgId == o.msgId && this.msgName.equals(o.msgName)) {
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		} 
	}

	@Override
	public int hashCode() {

		Integer k = Integer.valueOf(this.msgId);
		return k.hashCode();
	}

	@Override
	public String toString() {
		 
		StringBuilder sb = new StringBuilder(50);
		sb.append("msgId:").append(this.msgId);
		sb.append(",msgName:").append(this.msgName);
		sb.append(",msgMeta:").append(this.msgMeta);
		return sb.toString();
	}

	private MessageType(Class<? extends Message> meta) {
		
		this.msgId = meta.getName().hashCode();
		this.msgName = meta.getName();
		this.msgMeta = meta;
	}

	public int getMsgId() {
		return msgId;
	}

	public String getMsgName() {
		return msgName;
	}

	public Class<? extends Message> getMsgMeta() {
		return msgMeta;
	}
	
}
